package org.jsola.hr.service.impl;

import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.jsola.common.DateKit;
import org.jsola.core.Page;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.ExampleKit;
import org.jsola.hr.common.NumberKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dao.ISocDispatchDAO;
import org.jsola.hr.dto.SocDispatchAddDTO;
import org.jsola.hr.dto.SocDispatchUpdateDTO;
import org.jsola.hr.entity.SocDispatchDO;
import org.jsola.hr.entity.SocDispatchEmpAddDO;
import org.jsola.hr.entity.SocDispatchEmpLessDO;
import org.jsola.hr.entity.SocProgDO;
import org.jsola.hr.query.SocDispatchQuery;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.*;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 社保派单记录表
 *
 * @author zhr
 */
@Service("hrSocDispatchServiceImpl")
public class SocDispatchServiceImpl implements ISocDispatchService {

    @Autowired
    private ISocDispatchDAO socDispatchDAO;

    @Autowired
    private ISocDispatchEmpAddService socDispatchEmpAddService;

    @Autowired
    private ISocDispatchEmpLessService socDispatchEmpLessService;

    @Autowired
    private ISocDispatchCompanyService socDispatchCompanyService;

    @Autowired
    private IEmpSocMonthService empSocMonthService;

    @Autowired
    private ISocProgService socProgService;

    @Autowired
    private IGroupCityService groupCityService;

    @Autowired
    private IChildCompanyService childCompanyService;

    @Autowired
    private IGroupCompanyService groupCompanyService;
    
    private BigDecimal decimal0 = new BigDecimal(0);

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SocDispatchVO save(SocDispatchAddDTO socDispatchAddDTO, TokenUser tokenUser) {
        // 转DO
        SocDispatchDO socDispatchDO = socDispatchAddDTO.to(SocDispatchDO.class);
        // 增加导入记录名称
        addSocDispatchName(socDispatchDO, tokenUser.getSiteId());
        // 保存
        socDispatchDO = save(socDispatchDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return socDispatchDO.to(SocDispatchVO.class);
    }

    /**
     * 增加导入记录名称
     *
     * @param socDispatchDO 增加导入记录名称
     * @param siteId        站点
     */
    private void addSocDispatchName(SocDispatchDO socDispatchDO, String siteId) {
        if (StringUtils.isNotEmpty(socDispatchDO.getName())) {
            return;
        }
        // 当月已有的
        List<SocDispatchDO> list = listByYearAndMonth(socDispatchDO.getCompanyId(), socDispatchDO.getYear(), socDispatchDO.getMonth(), siteId);
        // 当前次数
        int nowCount = list.size() + 1;
        String numStr = NumberKit.formatNumber(nowCount);
        String name = socDispatchDO.getYear() + "年" + Integer.valueOf(socDispatchDO.getMonth()) + "月" + " 第" + numStr + "次导入记录";
        if (socDispatchDO.getAddOrLess()) {
            name = name + "（增员）";
        } else {
            name = name + "（减员）";
        }
        socDispatchDO.setName(name);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(SocDispatchUpdateDTO socDispatchUpdateDTO, TokenUser tokenUser) {
        //转DO
        SocDispatchDO socDispatchDO = socDispatchUpdateDTO.to(SocDispatchDO.class);
        //根据主键更新，只更新非null值
        return updateByIdSelective(socDispatchDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... socDispatchIds) {

        List<SocDispatchDO> socDispatchList = listSocDispatchByIds(tokenUser, socDispatchIds);
        if (CollectionUtils.isEmpty(socDispatchList)) {
            return 0;
        }
        // 校验是否派单
        List<String> hasSendList = socDispatchList.parallelStream()
                .filter(SocDispatchDO::getHasSend)
                .map(SocDispatchDO::getName)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(hasSendList)) {
            String names = String.join(",", hasSendList);
            throw new ParamException("社保派单记录'" + names + "'已完成派单,不能删除");
        }

        // 增员
        String[] addDispatchIds = socDispatchList.parallelStream()
                .filter(SocDispatchDO::getAddOrLess)
                .map(SocDispatchDO::getId)
                .toArray(String[]::new);
        // 增员删除子项
        if (addDispatchIds.length > 0) {
            socDispatchEmpAddService.deleteBySocDispatchId(tokenUser.getSiteId(), addDispatchIds);
        }
        // 减员
        String[] lessDispatchIds = socDispatchList.parallelStream()
                .filter(dispatch -> !dispatch.getAddOrLess())
                .map(SocDispatchDO::getId)
                .toArray(String[]::new);
        // 减员删除子项
        if (lessDispatchIds.length > 0) {
            socDispatchEmpLessService.deleteBySocDispatchId(tokenUser.getSiteId(), lessDispatchIds);
        }
        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) socDispatchIds);
    }

    /**
     * 根据主键查询多个导入记录
     *
     * @param tokenUser      当前用户
     * @param socDispatchIds 导入记录
     * @return 导入记录
     */
    private List<SocDispatchDO> listSocDispatchByIds(TokenUser tokenUser, String... socDispatchIds) {
        if (socDispatchIds == null || socDispatchIds.length == 0) {
            return null;
        }
        Example example = new Example(SocDispatchDO.class);
        example.and()
                .andIn("id", Arrays.asList(socDispatchIds))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());

        return socDispatchDAO.selectByExample(example);
    }


    @Override
    public SocDispatchVO selectById(String socDispatchId, String siteId) {
        SocDispatchDO socDispatchDO = selectDOById(socDispatchId, siteId);
        if (socDispatchDO == null) {
            return null;
        }
        return socDispatchDO.to(SocDispatchVO.class);
    }

    @Override
    public List<SocDispatchListVO> select(SocDispatchQuery socDispatchQuery, String siteId) {
        List<SocDispatchDO> socDispatchDOList = selectDO(socDispatchQuery, siteId);
        if(CollectionUtils.isEmpty(socDispatchDOList)) {
            return socDispatchDOList == null ? null : new ArrayList<>();
        }
        return socDispatchDOList.stream()
                .map(socDispatchDO -> socDispatchDO.to(SocDispatchListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(SocDispatchQuery socDispatchQuery, String siteId) {
        Example example = buildExample(socDispatchQuery,siteId);
        return socDispatchDAO.selectCountByExample(example);
    }

    @Override
    public Page<SocDispatchListVO> selectPage(SocDispatchQuery socDispatchQuery, String siteId) {
        Example example = buildExample(socDispatchQuery, siteId);
        Page<SocDispatchDO> page = socDispatchDAO.selectPageByExample(example,
                socDispatchQuery.getPageNo(),
                socDispatchQuery.getPageSize());

        Page<SocDispatchListVO> pageVo = page.to(SocDispatchListVO.class);
        if (!CollectionUtils.isEmpty(pageVo.getEntities())) {
            pageVo.getEntities().parallelStream().forEach(
                    // 获取统计数据
                    socDispatch -> getNumberToDispatch(socDispatch, siteId)
            );
        }
        return pageVo;
    }

    /**
     * 获取统计数据并添加
     *
     * @param socDispatch 派单记录
     * @param siteId      站点id
     */
    private void getNumberToDispatch(SocDispatchListVO socDispatch, String siteId) {
        SocDispatchNumber socDispatchNumber = new SocDispatchNumber();

        if (socDispatch.getAddOrLess()) {
            // 增员
            getEmpAddSum(socDispatchNumber, siteId, socDispatch.getId());
        } else {
            // 减员
            getEmpLessSum(socDispatchNumber, siteId, socDispatch.getId());
        }
        int numAll = socDispatchNumber.getNumAll();
        int numHasFinish = socDispatchNumber.getNumHasFinish();
        int numError = socDispatchNumber.getNumError();
        socDispatch.setNumAll(numAll);
        socDispatch.setNumNotFinish(socDispatchNumber.getNumNotFinish());
        socDispatch.setNumHasFinish(numHasFinish);
        socDispatch.setNumError(numError);
        socDispatch.setNumImportError(socDispatchNumber.getNumImportError());
        socDispatch.setNumImportNoError(socDispatchNumber.getNumImportNoError());

        socDispatch.setIsFinishAll(numHasFinish + numError == numAll);
    }

    @Override
    public SocDispatchDO selectDOById(String socDispatchId, String siteId) {
        return listById(socDispatchId, siteId);
    }

    @Override
    public List<SocDispatchDO> selectDO(SocDispatchQuery socDispatchQuery, String siteId) {
        Example example = buildExample(socDispatchQuery,siteId);
        return socDispatchDAO.selectByExample(example);
    }

    @Override
    public List<SocDispatchDO> listByYearAndMonth(String companyId, String year, String month, String siteId) {
        Example example = new Example(SocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("year", year)
                .andEqualTo("month", month)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return socDispatchDAO.selectByExample(example);
    }

    @Data
    private class SocDispatchNumber {
        int numAll = 0;
        int numHasFinish = 0;
        int numNotFinish = 0;
        int numError = 0;
        int numImportError = 0;
        int numImportNoError = 0;
    }

    @Override
    public SocDispatchLastMonthVO getLastMonthInfo(String companyId, String year, String month, TokenUser tokenUser) {
        // 拼装时间
        String dateStr = year + "-" + month;
        Date dateQuery = DateKit.getDate("yyyy-MM", dateStr);
        // 获取上月时间
        Date dateLast = DateKit.getBeforeMonth(dateQuery, -1);
        String yearLast = DateKit.getDateStr(dateLast, "yyyy");
        String monthLast = DateKit.getDateStr(dateLast, "MM");

        // 上月已派单且已接单的
        Example example = new Example(SocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("year", yearLast)
                .andEqualTo("month", monthLast)
                .andEqualTo("hasSend", true)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        // 派单记录
        List<SocDispatchDO> socDispatchList = socDispatchDAO.selectByExample(example);

        // 上月情况
        SocDispatchLastMonthVO socDispatchLastMonth = new SocDispatchLastMonthVO();
        socDispatchLastMonth.setYearLast(yearLast);
        socDispatchLastMonth.setMonthLast(monthLast);
        if (CollectionUtils.isEmpty(socDispatchList)) {
            socDispatchLastMonth.setSendCountLast(0);
        } else {
            SocDispatchNumber socDispatchNumber = new SocDispatchNumber();

            // 增员
            String[] addDispatchIds = socDispatchList.parallelStream()
                    .filter(SocDispatchDO::getAddOrLess)
                    .map(SocDispatchDO::getId).toArray(String[]::new);
            // 增员具体人员
            if (addDispatchIds.length > 0) {
                // 增加增员的人员统计
                getEmpAddSum(socDispatchNumber, tokenUser.getSiteId(), addDispatchIds);
            }

            // 减员
            String[] lessDispatchIdList = socDispatchList.parallelStream()
                    .filter(dispatch -> !dispatch.getAddOrLess())
                    .map(SocDispatchDO::getId).toArray(String[]::new);
            // 减员具体人员
            if (lessDispatchIdList.length > 0) {
                // 增加减员员的人员统计
                getEmpLessSum(socDispatchNumber, tokenUser.getSiteId(), addDispatchIds);
            }

            // 放值
            socDispatchLastMonth.setSendCountLast(socDispatchList.size());
            socDispatchLastMonth.setNumAllLast(socDispatchNumber.getNumAll());
            socDispatchLastMonth.setNumHasFinishLast(socDispatchNumber.getNumHasFinish());
            socDispatchLastMonth.setNumNotFinishLast(socDispatchNumber.getNumNotFinish());
            socDispatchLastMonth.setNumErrorLast(socDispatchNumber.getNumError());
        }

        return socDispatchLastMonth;
    }

    /**
     * 增员人员统计
     *
     * @param socDispatchNumber 统计后人员
     * @param siteId            站点
     * @param addDispatchIds    增员记录id
     */
    private void getEmpAddSum(SocDispatchNumber socDispatchNumber, String siteId, String... addDispatchIds) {
        if (addDispatchIds == null || addDispatchIds.length == 0) {
            return;
        }
        List<SocDispatchEmpAddDO> addList = socDispatchEmpAddService.listBySocDispatchIds(siteId, addDispatchIds);

        if (!CollectionUtils.isEmpty(addList)) {
            addList.forEach(
                    // 根据状态增加员工统计数量
                    empAddDO -> getNumberByEmpStatus(empAddDO.getStatus(), empAddDO.getNoError(), socDispatchNumber)
            );
        }
    }

    /**
     * 减员人员统计
     *
     * @param socDispatchNumber 统计后人员
     * @param siteId            站点
     * @param lessDispatchIds   减员记录id
     */
    private void getEmpLessSum(SocDispatchNumber socDispatchNumber, String siteId, String... lessDispatchIds) {
        if (lessDispatchIds == null || lessDispatchIds.length == 0) {
            return;
        }
        List<SocDispatchEmpLessDO> lessList = socDispatchEmpLessService.listBySocDispatchIds(siteId, lessDispatchIds);

        if (!CollectionUtils.isEmpty(lessList)) {
            lessList.forEach(
                    // 根据状态增加员工统计数量
                    empLessDO -> getNumberByEmpStatus(empLessDO.getStatus(), empLessDO.getNoError(), socDispatchNumber)
            );
        }
    }

    /**
     * 根据状态增加员工统计数量
     *
     * @param status            状态
     * @param importNoError     导入是否有错误
     * @param socDispatchNumber 统计数量
     */
    private void getNumberByEmpStatus(Integer status, boolean importNoError, SocDispatchNumber socDispatchNumber) {
        socDispatchNumber.setNumAll(socDispatchNumber.getNumAll() + 1);

        // 派单状态(0:未完成,1:已完成,2:错误)
        if (status == 0) {
            socDispatchNumber.setNumNotFinish(socDispatchNumber.getNumNotFinish() + 1);
        } else if (status == 1) {
            socDispatchNumber.setNumHasFinish(socDispatchNumber.getNumHasFinish() + 1);
        } else if (status == 2) {
            socDispatchNumber.setNumError(socDispatchNumber.getNumError() + 1);
        }
        if (importNoError) {
            socDispatchNumber.setNumImportNoError(socDispatchNumber.getNumImportNoError() + 1);
        } else {
            socDispatchNumber.setNumImportError(socDispatchNumber.getNumImportError() + 1);
        }
    }

    @Override
    public SocDetailsDispatchVO findDetailsById(String socDispatchId, String siteId) {
        SocDispatchDO socDispatch = selectDOById(socDispatchId, siteId);
        if (Objects.isNull(socDispatch)) {
            throw new ParamException("派单记录不存在");
        }
        // 派单记录人数统计
        SocDispatchNumber socDispatchNumber = new SocDispatchNumber();
        // 增员还是减员
        SocDetailsDispatchVO dispatch = socDispatch.to(SocDetailsDispatchVO.class);
        if (dispatch.getAddOrLess()) {
            // 增员人数统计
            getEmpAddSum(socDispatchNumber, siteId, socDispatch.getId());

            // 个人社保合计
            BigDecimal personalSocAmount = decimal0;
            // 个人公积金合计
            BigDecimal personalPfAmount = decimal0;
            // 公司社保合计
            BigDecimal companySocAmount = decimal0;
            // 公司公积金合计
            BigDecimal companyPfAmount = decimal0;

            // 增员
            List<SocDispatchEmpAddDO> dispatchEmpAddList = socDispatchEmpAddService.listBySocDispatchId(dispatch.getId(), siteId);
            if (!CollectionUtils.isEmpty(dispatchEmpAddList)) {
                // 筛选
                for (SocDispatchEmpAddDO empAdd : dispatchEmpAddList) {
                    // 统计
                    personalSocAmount = NumberKit.decimalAdd(personalSocAmount, empAdd.getPersonalSocAmount());
                    personalPfAmount = NumberKit.decimalAdd(personalPfAmount, empAdd.getPersonalPfAmount());
                    companySocAmount = NumberKit.decimalAdd(companySocAmount, empAdd.getCompanySocAmount());
                    companyPfAmount = NumberKit.decimalAdd(companyPfAmount, empAdd.getCompanyPfAmount());
                }
            }

            BigDecimal personalAllAmount = NumberKit.decimalAdd(personalSocAmount, personalPfAmount);
            BigDecimal companyAllAmount = NumberKit.decimalAdd(companySocAmount, companyPfAmount);
            BigDecimal allAmount = NumberKit.decimalAdd(personalAllAmount, companyAllAmount);

            dispatch.setPersonalSocAmount(personalSocAmount);
            dispatch.setPersonalPfAmount(personalPfAmount);

            dispatch.setPersonalAllAmount(personalAllAmount);
            dispatch.setCompanySocAmount(companySocAmount);
            dispatch.setCompanyPfAmount(companyPfAmount);
            dispatch.setCompanyAllAmount(companyAllAmount);
            dispatch.setAllAmount(allAmount);
        } else {
            // 减员人数统计
            getEmpLessSum(socDispatchNumber, siteId, socDispatch.getId());
        }
        dispatch.setNumAll(socDispatchNumber.getNumAll());
        dispatch.setNumNotFinish(socDispatchNumber.getNumNotFinish());
        dispatch.setNumHasFinish(socDispatchNumber.getNumHasFinish());
        dispatch.setNumError(socDispatchNumber.getNumError());
        dispatch.setNumImportError(socDispatchNumber.getNumImportError());
        dispatch.setNumImportNoError(socDispatchNumber.getNumImportNoError());
        return dispatch;
    }



    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer dispatchSend(String socDispatchId, TokenUser tokenUser) {
        SocDispatchDO socDispatch = selectDOById(socDispatchId, tokenUser.getSiteId());
        if (Objects.isNull(socDispatch)) {
            throw new ParamException("派单记录不存在");
        }
        if (socDispatch.getHasSend()) {
            return 0;
        }
        List<String> errorList;
        int empNum;
        List<String> socDispatchEmpIdList;
        if (socDispatch.getAddOrLess()) {
            // 增员
            List<SocDispatchEmpAddDO> dispatchEmpAddList = socDispatchEmpAddService.listBySocDispatchId(socDispatch.getId(), tokenUser.getSiteId());
            socDispatchEmpIdList = dispatchEmpAddList.stream()
                    .map(SocDispatchEmpAddDO::getId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(dispatchEmpAddList)) {
                throw new ParamException("没有需要派单的人员,请检查");
            }
            empNum = dispatchEmpAddList.size();
            // 有错误的员工
            errorList = dispatchEmpAddList.parallelStream()
                    .filter(dispatchAdd -> !dispatchAdd.getNoError())
                    .map(SocDispatchEmpAddDO::getName)
                    .collect(Collectors.toList());
        } else {
            // 减员
            List<SocDispatchEmpLessDO> dispatchEmpLessList = socDispatchEmpLessService.listBySocDispatchId(socDispatch.getId(), tokenUser.getSiteId());
            if (CollectionUtils.isEmpty(dispatchEmpLessList)) {
                throw new ParamException("没有需要派单的人员,请检查");
            }
            socDispatchEmpIdList = dispatchEmpLessList.stream()
                    .map(SocDispatchEmpLessDO::getId).collect(Collectors.toList());
            empNum = dispatchEmpLessList.size();
            // 有错误的员工
            errorList = dispatchEmpLessList.parallelStream()
                    .filter(dispatchLess -> !dispatchLess.getNoError())
                    .map(SocDispatchEmpLessDO::getName)
                    .collect(Collectors.toList());
        }
        if (!CollectionUtils.isEmpty(errorList)) {
            String errorNames = String.join(",", errorList);
            throw new ParamException("人员'" + errorNames + "'的导入记录尚存在问题,不能派单");
        }
        // 根据派单次数获取派单名称
        String sendName = getSendName(socDispatch, tokenUser.getSiteId());
        // 修改
        SocDispatchDO dispatchUp = new SocDispatchDO();
        dispatchUp.setId(socDispatchId);
        dispatchUp.setName(sendName);
        dispatchUp.setHasSend(true);
        socDispatchDAO.updateByPrimaryKeySelective(dispatchUp);
        // 人员修改派单状态
        if (socDispatch.getAddOrLess()) {
            // 增员
            socDispatchEmpAddService.sendBySocDispatchId(socDispatch.getId(), tokenUser.getSiteId());
        } else {
            // 增员
            socDispatchEmpLessService.sendBySocDispatchId(socDispatch.getId(), tokenUser.getSiteId());
        }
        // 公司派单记录的生成
        socDispatchCompanyService.addCompanySocDispatch(socDispatch, socDispatchEmpIdList, tokenUser);
        return empNum;
    }

    private String getSendName(SocDispatchDO socDispatch, String siteId) {
        Example example = new Example(SocDispatchDO.class);
        example.and()
                .andEqualTo("companyId", socDispatch.getCompanyId())
                .andEqualTo("hasSend", true)
                .andEqualTo("year", socDispatch.getYear())
                .andEqualTo("month", socDispatch.getMonth())
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        int count = socDispatchDAO.selectCountByExample(example);
        // 当前次数
        int nowCount = count + 1;
        String numStr = NumberKit.formatNumber(nowCount);
        String name = socDispatch.getYear() + "年" + Integer.valueOf(socDispatch.getMonth()) + "月" + " 第" + numStr + "次派单";
        if (socDispatch.getAddOrLess()) {
            name = name + "（增员）";
        } else {
            name = name + "（减员）";
        }
        return name;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public SocDispatchVO addOrUpdateSocDispatch(String companyId, String socDispatchId, boolean isUpdate, boolean addOrLess, String year, String month, TokenUser tokenUser) {
        SocDispatchVO socDispatch;
        // 拼装公告部分
        SocDispatchDO socDispatchDO = new SocDispatchDO();
        socDispatchDO.setCompanyId(companyId);
        socDispatchDO.setYear(year);
        socDispatchDO.setMonth(month);
        socDispatchDO.setAddOrLess(addOrLess);
        socDispatchDO.setHasSend(false);
        socDispatchDO.setHasReceive(false);
        // 修改
        if (isUpdate) {
            socDispatch = selectById(socDispatchId, tokenUser.getSiteId());
            ParamException.notNull(socDispatch, "员工社保派单记录不存在,不需要重新导入");

            // 删除旧的员工导入记录
            if (socDispatch.getAddOrLess()) {
                // 增员
                socDispatchEmpAddService.deleteBySocDispatchId(tokenUser.getSiteId(), socDispatchId);
            } else {
                // 减员
                socDispatchEmpLessService.deleteBySocDispatchId(tokenUser.getSiteId(), socDispatchId);
            }

            // 修改
            SocDispatchUpdateDTO updateDTO = socDispatchDO.to(SocDispatchUpdateDTO.class);
            updateDTO.setId(socDispatchId);
            // 修改
            update(updateDTO, tokenUser);
        } else {
            // 生成导入记录
            SocDispatchAddDTO socDispatchAddDTO = socDispatchDO.to(SocDispatchAddDTO.class);
            // 导入记录保存
            socDispatch = save(socDispatchAddDTO, tokenUser);
        }
        return socDispatch;
    }

    @Override
    public void checkYearAndMonth(String companyId, String year, String month, String siteId) {
        ParamException.hasLength(companyId, "公司id不能为空");
        ParamException.hasLength(year, "年不能为空");
        ParamException.hasLength(month, "月不能为空");
        // 校验参保月是否创建
        boolean exists = empSocMonthService.existsByYearAndMonth(companyId, year, month, siteId);

        if (!exists) {
            throw new ParamException("尚未创建" + year + "年" + month + "的参保记录,请先去参保管理中创建");
        }
    }

    @Override
    public List<ChildCompanyListVO> listChildCompanyBySoc(String socId, String companyId, String siteId) {
        SocProgDO socProg = socProgService.selectDOById(socId, siteId);
        ParamException.notNull(socProg, "参保方案不存在或已删除");

        // 获取分管该地区的分公司
        List<String> groupList = groupCityService.listByCity(socProg.getSocCity(), siteId);
        // 筛选拥有管理本用工单位权限的分公司
        groupList = groupCompanyService.listHasRoleInCompany(groupList, companyId, siteId);

        if (!CollectionUtils.isEmpty(groupList)) {
            return childCompanyService.listByIdList(groupList, siteId);
        }
        return null;
    }


    /**
     * 根据查询参数，构建example

     * @param socDispatchQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(SocDispatchQuery socDispatchQuery, String siteId) {
        Example example = new Example(SocDispatchDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        if (socDispatchQuery.getCompanyId() != null) {
            example.and().andEqualTo("companyId", socDispatchQuery.getCompanyId());
        }
        if (socDispatchQuery.getYear() != null) {
            example.and().andEqualTo("year", socDispatchQuery.getYear());
        }
        if (socDispatchQuery.getMonth() != null) {
            example.and().andEqualTo("month", socDispatchQuery.getMonth());
        }
        if (socDispatchQuery.getName() != null) {
            example.and().andEqualTo("name", socDispatchQuery.getName());
        }
        if (socDispatchQuery.getAddOrLess() != null) {
            example.and().andEqualTo("addOrLess", socDispatchQuery.getAddOrLess());
        }
        if (socDispatchQuery.getHasSend() != null) {
            example.and().andEqualTo("hasSend", socDispatchQuery.getHasSend());
        }
        if (socDispatchQuery.getHasReceive() != null) {
            example.and().andEqualTo("hasReceive", socDispatchQuery.getHasReceive());
        }
        // 排序
        if (CollectionUtils.isEmpty(socDispatchQuery.getOrders())) {
            example.orderBy("gmtCreate").desc();
        } else {
            ExampleKit.setExampleOrder(example, socDispatchQuery.getOrders());
        }
        return example;
    }
}




